{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# [ Chapter 8 - Signals Boosting Models ]\n",
    "# Signals Boosting"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "NOTE: This notebook depends upon the the Retrotech dataset. If you have any issues, please rerun the [Setting up the Retrotech Dataset](../ch04/1.setting-up-the-retrotech-dataset.ipynb) notebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from datetime import datetime\n",
    "from pyspark.sql import SparkSession\n",
    "\n",
    "from aips import display_product_search, get_engine\n",
    "from aips.spark import create_view_from_collection\n",
    "from aips.spark.dataframe import from_sql\n",
    "\n",
    "spark = SparkSession.builder.appName(\"AIPS\").getOrCreate()\n",
    "engine = get_engine()\n",
    "signals_collection = engine.get_collection(\"signals\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Keyword Search with No Signals Boosting"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Figure 8.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#%run chapters/ch04/1.setting-up-the-retrotech-dataset.ipynb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# %load -s product_search_request aips/search_requests\n",
    "def product_search_request(query, param_overrides={}):\n",
    "    request = {\"query\": query,\n",
    "               \"query_fields\": [\"name\", \"manufacturer\", \"long_description\"],\n",
    "               \"return_fields\": [\"upc\", \"name\", \"manufacturer\",\n",
    "                                 \"short_description\", \"score\"],\n",
    "               \"limit\": 5,\n",
    "               \"order_by\": [(\"score\", \"desc\"), (\"upc\", \"asc\")]}\n",
    "    return request | param_overrides"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div id=\"demo\">\n",
       "\t<center><input style=\"width:40%\" readonly type=\"text\" name=\"q\" value=\"ipad\">\n",
       "\t<input readonly type=\"submit\" value=\"Search\">\n",
       "\t</center>\n",
       "    <div class=\"results\">\n",
       "    \t\n",
       "\n",
       "    </div>\n",
       "</div>\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/400037252074.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> iPad&#xAE; - Refurbished Digital A/V Adapter\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> iPad&#xAE;</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/400037252258.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> iPad&#xAE; - Refurbished USB Power Adapter\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> iPad&#xAE;</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/400037252616.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> iPad&#xAE; - Refurbished Dock Connector-to-VGA Adapter\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> iPad&#xAE;</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/400037252890.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> iPad&#xAE; - Refurbished Keyboard Dock\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> iPad&#xAE;</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/400037253316.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> iPad&#xAE; - Refurbished Digital Camera Connection Kit\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> iPad&#xAE;</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "products_collection = engine.get_collection(\"products\")\n",
    "query = \"ipad\"\n",
    "request = product_search_request(query)\n",
    "response = products_collection.search(**request)\n",
    "display_product_search(query, response[\"docs\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create Signals Boosts (Signals Aggregation)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Basic Signals Boosting Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def aggregate_signals(signals_collection, collection_name, signals_agg_query):\n",
    "    print(\"Aggregating Signals to Create Signals Boosts...\")\n",
    "    create_view_from_collection(signals_collection, \"signals\")\n",
    "    collection = engine.create_collection(collection_name)\n",
    "    collection.write(from_sql(signals_agg_query))\n",
    "    collection.commit()\n",
    "    print(\"Signals Aggregation Completed!\")\n",
    "    return collection"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Search with Signals Boosts Applied"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Signals Boosting Query"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Raw Signals Boosts (Case-sensitive)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Listing 8.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# %load -s search_for_boosts aips/search_requests\n",
    "def search_for_boosts(query, collection, query_field=\"query\"):\n",
    "    boosts_request = {\"query\": query,\n",
    "                      \"query_fields\": [query_field],\n",
    "                      \"return_fields\": [\"query\", \"doc\", \"boost\"],\n",
    "                      \"limit\": 20,\n",
    "                      \"order_by\": [(\"boost\", \"desc\")]}\n",
    "    response = collection.search(**boosts_request)\n",
    "    return response[\"docs\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def create_boosting_collection(collection_name):\n",
    "    basic_signals_aggregation_query = \"\"\"\n",
    "    SELECT q.target AS query, c.target AS doc,\n",
    "    COUNT(c.target) AS boost\n",
    "    FROM signals c LEFT JOIN signals q\n",
    "    ON c.query_id = q.query_id\n",
    "    WHERE c.type = 'click' AND q.type = 'query'\n",
    "    GROUP BY q.target, doc\n",
    "    ORDER BY boost DESC\n",
    "    \"\"\"\n",
    "    collection = engine.get_collection(collection_name)\n",
    "    return aggregate_signals(collection, \"basic_signals_boosts\", basic_signals_aggregation_query)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def show_raw_boosted_queries(boost_documents):\n",
    "    boosted_queries = \"\\n\".join([f'\"{doc[\"query\"]}\" : {doc[\"boost\"]}'\n",
    "                                 for doc in boost_documents])\n",
    "    print(\"Raw Boosted Queries\")\n",
    "    print(boosted_queries)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Aggregating Signals to Create Signals Boosts...\n",
      "Wiping \"basic_signals_boosts\" collection\n",
      "Creating \"basic_signals_boosts\" collection\n",
      "Status: Success\n",
      "Successfully written 197169 documents\n",
      "Signals Aggregation Completed!\n"
     ]
    }
   ],
   "source": [
    "signals_boosting_collection = create_boosting_collection(\"signals\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Raw Boosted Queries\n",
      "\"iPad\" : 1050\n",
      "\"ipad\" : 966\n",
      "\"Ipad\" : 829\n",
      "\"iPad 2\" : 509\n",
      "\"ipad 2\" : 347\n",
      "\"Ipad2\" : 261\n",
      "\"ipad2\" : 238\n",
      "\"Ipad 2\" : 213\n",
      "\"I pad\" : 203\n",
      "\"i pad\" : 133\n",
      "\"IPad\" : 77\n",
      "\"Apple\" : 76\n",
      "\"I pad 2\" : 60\n",
      "\"apple ipad\" : 55\n",
      "\"Apple iPad\" : 53\n",
      "\"ipads\" : 43\n",
      "\"tablets\" : 42\n",
      "\"apple\" : 41\n",
      "\"iPads\" : 38\n",
      "\"i pad 2\" : 38\n"
     ]
    }
   ],
   "source": [
    "query = \"885909457588\" #most popular iPad model\n",
    "signals_docs = search_for_boosts(query, signals_boosting_collection, \"doc\")\n",
    "show_raw_boosted_queries(signals_docs)    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Normalized Signals Boosting (Case-insensitive)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Listing 8.2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Aggregating Signals to Create Signals Boosts...\n",
      "Wiping \"normalized_signals_boosts\" collection\n",
      "Creating \"normalized_signals_boosts\" collection\n",
      "Status: Success\n",
      "Successfully written 152252 documents\n",
      "Signals Aggregation Completed!\n"
     ]
    }
   ],
   "source": [
    "normalized_signals_aggregation_query = \"\"\"\n",
    "SELECT LOWER(q.target) AS query,\n",
    "c.target AS doc, COUNT(c.target) AS boost\n",
    "FROM signals c LEFT JOIN signals q ON c.query_id = q.query_id\n",
    "WHERE c.type = 'click' AND q.type = 'query'\n",
    "GROUP BY LOWER(q.target), doc\n",
    "ORDER BY boost DESC\"\"\"\n",
    "\n",
    "normalized_collection = \\\n",
    "  aggregate_signals(signals_collection, \"normalized_signals_boosts\",\n",
    "                    normalized_signals_aggregation_query)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Raw Boosted Queries\n",
      "\"ipad\" : 2939\n",
      "\"ipad 2\" : 1104\n",
      "\"ipad2\" : 540\n",
      "\"i pad\" : 341\n",
      "\"apple ipad\" : 152\n",
      "\"ipads\" : 123\n",
      "\"apple\" : 118\n",
      "\"i pad 2\" : 99\n",
      "\"tablets\" : 67\n",
      "\"tablet\" : 61\n",
      "\"ipad 1\" : 52\n",
      "\"apple ipad 2\" : 27\n",
      "\"hp touchpad\" : 26\n",
      "\"ipaq\" : 20\n",
      "\"i pad2\" : 19\n",
      "\"wi\" : 19\n",
      "\"apple computers\" : 18\n",
      "\"apple i pad\" : 15\n",
      "\"ipad 2 16gb\" : 15\n",
      "\"samsung galaxy\" : 14\n"
     ]
    }
   ],
   "source": [
    "query = \"885909457588\" #most popular iPad model\n",
    "signals_docs = search_for_boosts(query, normalized_collection, \"doc\")\n",
    "show_raw_boosted_queries(signals_docs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Star Wars Search before User Manipulation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Figure 8.2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# %load -s create_boosts_query,boosted_product_search_request aips/search_requests\n",
    "def create_boosts_query(boost_documents):\n",
    "    print(\"Boost Documents:\")\n",
    "    display(boost_documents)\n",
    "    boosts = \" \".join([f'\"{b[\"doc\"]}\"^{b[\"boost\"]}' \n",
    "                       for b in boost_documents])\n",
    "    print(f\"\\nBoost Query: \\n{boosts}\\n\")\n",
    "    return boosts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "def boosted_product_search_request(query, collection, boost_field=None):\n",
    "    signals_documents = search_for_boosts(query, collection)\n",
    "    signals_boosts = create_boosts_query(signals_documents)\n",
    "    boosted_request = product_search_request(query)\n",
    "    if boost_field:\n",
    "        signals_boosts = (boost_field, signals_boosts)\n",
    "    boosted_request[\"query_boosts\"] = signals_boosts\n",
    "    return boosted_request"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Boost Documents:\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[{'query': 'star wars', 'doc': '45626176', 'boost': 5000},\n",
       " {'query': 'star wars', 'doc': '024543742180', 'boost': 1490},\n",
       " {'query': 'star wars', 'doc': '400032015667', 'boost': 186},\n",
       " {'query': 'star wars', 'doc': '024543742074', 'boost': 127},\n",
       " {'query': 'star wars', 'doc': '024543559856', 'boost': 117},\n",
       " {'query': 'star wars', 'doc': '014633169546', 'boost': 107},\n",
       " {'query': 'star wars', 'doc': '024543742098', 'boost': 81},\n",
       " {'query': 'star wars', 'doc': '024543781875', 'boost': 67},\n",
       " {'query': 'star wars', 'doc': '023272342654', 'boost': 39},\n",
       " {'query': 'star wars', 'doc': '014633169522', 'boost': 32},\n",
       " {'query': 'star wars', 'doc': '024543560067', 'boost': 30},\n",
       " {'query': 'star wars', 'doc': '883929154012', 'boost': 24},\n",
       " {'query': 'star wars', 'doc': '023272342630', 'boost': 20},\n",
       " {'query': 'star wars', 'doc': '708431390614', 'boost': 18},\n",
       " {'query': 'star wars', 'doc': '024543263739', 'boost': 18},\n",
       " {'query': 'star wars', 'doc': '886973561621', 'boost': 17},\n",
       " {'query': 'star wars', 'doc': '023272341381', 'boost': 16},\n",
       " {'query': 'star wars', 'doc': '030206742121', 'boost': 14},\n",
       " {'query': 'star wars', 'doc': '885370332889', 'boost': 12},\n",
       " {'query': 'star wars', 'doc': '883929106172', 'boost': 8}]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Boost Query: \n",
      "\"45626176\"^5000 \"024543742180\"^1490 \"400032015667\"^186 \"024543742074\"^127 \"024543559856\"^117 \"014633169546\"^107 \"024543742098\"^81 \"024543781875\"^67 \"023272342654\"^39 \"014633169522\"^32 \"024543560067\"^30 \"883929154012\"^24 \"023272342630\"^20 \"708431390614\"^18 \"024543263739\"^18 \"886973561621\"^17 \"023272341381\"^16 \"030206742121\"^14 \"885370332889\"^12 \"883929106172\"^8\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div id=\"demo\">\n",
       "\t<center><input style=\"width:40%\" readonly type=\"text\" name=\"q\" value=\"star wars\">\n",
       "\t<input readonly type=\"submit\" value=\"Search\">\n",
       "\t</center>\n",
       "    <div class=\"results\">\n",
       "    \t\n",
       "\n",
       "    </div>\n",
       "</div>\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/45626176.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Trash Can (Star Wars Themed)\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> Jay Franco & Sons</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/400032015667.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Star Wars - The Complete Saga - Blu-ray Disc\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> LucasFilm</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/883929154012.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Star Wars: The Clone Wars - The Complete Season Three [4 Discs] - DVD\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> LucasFilm</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/886973561621.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Star Wars: The Clone War - Original Soundtrack - CD\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> Sony Classics</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/708431390614.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> LeapFrog - Leapster Explorer Learning Game: Star Wars The Clone Wars\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> LeapFrog</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "query = '\"star wars\"'\n",
    "boosted_request = boosted_product_search_request(query, normalized_collection, \"upc\")\n",
    "boosted_request[\"filter\"] = [(\"-upc\", \"45626176\")]\n",
    "\n",
    "response = products_collection.search(**boosted_request)\n",
    "display_product_search(\"star wars\", response[\"docs\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Simulating a malicious user"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Listing 8.3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Adding Documents to 'signals' collection\n",
      "Aggregating Signals to Create Signals Boosts...\n",
      "Wiping \"signals_boosts_with_spam\" collection\n",
      "Creating \"signals_boosts_with_spam\" collection\n",
      "Status: Success\n",
      "Successfully written 152252 documents\n",
      "Signals Aggregation Completed!\n"
     ]
    }
   ],
   "source": [
    "signals_collection = engine.get_collection(\"signals\")\n",
    "spam_user = \"u8675309\"\n",
    "spam_query = \"star wars\"\n",
    "spam_signal_boost_doc_upc = \"45626176\" #doc for a \"trash compactor\" from someone who wants star wars is rubbish!\n",
    "\n",
    "signal_docs = []\n",
    "for num in range(5000): #generate 5,000 query and click signals\n",
    "    query_id = f\"u8675309_0_{num}\"\n",
    "    query_signal = { \n",
    "        \"query_id\": query_id,\n",
    "        \"user\": spam_user,\n",
    "        \"type\": \"query\",\n",
    "        \"target\": spam_query,\n",
    "        \"signal_time\": datetime.now().strftime(\"%Y-%m-%dT%H:%M:%SZ\")\n",
    "    }\n",
    "    click_signal = { \n",
    "        \"query_id\": query_id,\n",
    "        \"user\": spam_user,\n",
    "        \"type\": \"click\",\n",
    "        \"target\": spam_signal_boost_doc_upc,\n",
    "        \"signal_time\": datetime.now().strftime(\"%Y-%m-%dT%H:%M:%SZ\")\n",
    "    }\n",
    "    signal_docs.extend([click_signal, query_signal])\n",
    "\n",
    "signals_collection.add_documents(signal_docs)\n",
    "#re-run the basic signals aggregation to process the malicious clicks\n",
    "\n",
    "spam_signals_collection = \\\n",
    "    aggregate_signals(signals_collection, \"signals_boosts_with_spam\",\n",
    "                      normalized_signals_aggregation_query)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Impact of Spam on Search Results"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Listing 8.4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Boost Documents:\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[{'query': 'star wars', 'doc': '45626176', 'boost': 20000},\n",
       " {'query': 'star wars', 'doc': '024543742180', 'boost': 1490},\n",
       " {'query': 'star wars', 'doc': '400032015667', 'boost': 186},\n",
       " {'query': 'star wars', 'doc': '024543742074', 'boost': 127},\n",
       " {'query': 'star wars', 'doc': '024543559856', 'boost': 117},\n",
       " {'query': 'star wars', 'doc': '014633169546', 'boost': 107},\n",
       " {'query': 'star wars', 'doc': '024543742098', 'boost': 81},\n",
       " {'query': 'star wars', 'doc': '024543781875', 'boost': 67},\n",
       " {'query': 'star wars', 'doc': '023272342654', 'boost': 39},\n",
       " {'query': 'star wars', 'doc': '014633169522', 'boost': 32},\n",
       " {'query': 'star wars', 'doc': '024543560067', 'boost': 30},\n",
       " {'query': 'star wars', 'doc': '883929154012', 'boost': 24},\n",
       " {'query': 'star wars', 'doc': '023272342630', 'boost': 20},\n",
       " {'query': 'star wars', 'doc': '708431390614', 'boost': 18},\n",
       " {'query': 'star wars', 'doc': '024543263739', 'boost': 18},\n",
       " {'query': 'star wars', 'doc': '886973561621', 'boost': 17},\n",
       " {'query': 'star wars', 'doc': '023272341381', 'boost': 16},\n",
       " {'query': 'star wars', 'doc': '030206742121', 'boost': 14},\n",
       " {'query': 'star wars', 'doc': '885370332889', 'boost': 12},\n",
       " {'query': 'star wars', 'doc': '886111287055', 'boost': 8}]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Boost Query: \n",
      "\"45626176\"^20000 \"024543742180\"^1490 \"400032015667\"^186 \"024543742074\"^127 \"024543559856\"^117 \"014633169546\"^107 \"024543742098\"^81 \"024543781875\"^67 \"023272342654\"^39 \"014633169522\"^32 \"024543560067\"^30 \"883929154012\"^24 \"023272342630\"^20 \"708431390614\"^18 \"024543263739\"^18 \"886973561621\"^17 \"023272341381\"^16 \"030206742121\"^14 \"885370332889\"^12 \"886111287055\"^8\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div id=\"demo\">\n",
       "\t<center><input style=\"width:40%\" readonly type=\"text\" name=\"q\" value=\"\"star wars\"\">\n",
       "\t<input readonly type=\"submit\" value=\"Search\">\n",
       "\t</center>\n",
       "    <div class=\"results\">\n",
       "    \t\n",
       "\n",
       "    </div>\n",
       "</div>\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/45626176.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Trash Can (Star Wars Themed)\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> Jay Franco & Sons</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/400032015667.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Star Wars - The Complete Saga - Blu-ray Disc\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> LucasFilm</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/883929154012.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Star Wars: The Clone Wars - The Complete Season Three [4 Discs] - DVD\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> LucasFilm</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/886973561621.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Star Wars: The Clone War - Original Soundtrack - CD\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> Sony Classics</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/708431390614.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> LeapFrog - Leapster Explorer Learning Game: Star Wars The Clone Wars\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> LeapFrog</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# function boosted_product_search_request defined above before figure 8.2 code\n",
    "\n",
    "query = '\"star wars\"'\n",
    "boosted_request = boosted_product_search_request(query,\n",
    "                      spam_signals_collection, \"upc\")\n",
    "response = products_collection.search(**boosted_request)\n",
    "display_product_search(query, response[\"docs\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Fighting Signal Spam through User-level Deduplication"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Listing 8.5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Aggregating Signals to Create Signals Boosts...\n",
      "Wiping \"signals_boosts_anti_spam\" collection\n",
      "Creating \"signals_boosts_anti_spam\" collection\n",
      "Status: Success\n",
      "Successfully written 152252 documents\n",
      "Signals Aggregation Completed!\n"
     ]
    }
   ],
   "source": [
    "#One Signal per User - Anti-Spam\n",
    "anti_spam_aggregation_query = \"\"\"\n",
    "SELECT query, doc, COUNT(doc) AS boost FROM (\n",
    "  SELECT c.user unique_user, LOWER(q.target) AS query, c.target AS doc,\n",
    "  MAX(c.signal_time) AS boost\n",
    "  FROM signals c LEFT JOIN signals q ON c.query_id = q.query_id\n",
    "  WHERE c.type = 'click' AND q.type = 'query'\n",
    "  GROUP BY unique_user, LOWER(q.target), doc)\n",
    "GROUP BY query, doc\n",
    "ORDER BY boost DESC\"\"\"\n",
    "\n",
    "anti_spam_collection = \\\n",
    "    aggregate_signals(signals_collection, \"signals_boosts_anti_spam\",\n",
    "                      anti_spam_aggregation_query)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Boost Documents:\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[{'query': 'star wars', 'doc': '024543742180', 'boost': 1489},\n",
       " {'query': 'star wars', 'doc': '400032015667', 'boost': 186},\n",
       " {'query': 'star wars', 'doc': '024543742074', 'boost': 127},\n",
       " {'query': 'star wars', 'doc': '024543559856', 'boost': 117},\n",
       " {'query': 'star wars', 'doc': '014633169546', 'boost': 107},\n",
       " {'query': 'star wars', 'doc': '024543742098', 'boost': 81},\n",
       " {'query': 'star wars', 'doc': '024543781875', 'boost': 67},\n",
       " {'query': 'star wars', 'doc': '023272342654', 'boost': 39},\n",
       " {'query': 'star wars', 'doc': '014633169522', 'boost': 32},\n",
       " {'query': 'star wars', 'doc': '024543560067', 'boost': 30},\n",
       " {'query': 'star wars', 'doc': '883929154012', 'boost': 24},\n",
       " {'query': 'star wars', 'doc': '023272342630', 'boost': 20},\n",
       " {'query': 'star wars', 'doc': '708431390614', 'boost': 18},\n",
       " {'query': 'star wars', 'doc': '024543263739', 'boost': 18},\n",
       " {'query': 'star wars', 'doc': '886973561621', 'boost': 17},\n",
       " {'query': 'star wars', 'doc': '023272341381', 'boost': 16},\n",
       " {'query': 'star wars', 'doc': '030206742121', 'boost': 14},\n",
       " {'query': 'star wars', 'doc': '885370332889', 'boost': 12},\n",
       " {'query': 'star wars', 'doc': '883929106172', 'boost': 8},\n",
       " {'query': 'star wars', 'doc': '886111287055', 'boost': 8}]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Boost Query: \n",
      "\"024543742180\"^1489 \"400032015667\"^186 \"024543742074\"^127 \"024543559856\"^117 \"014633169546\"^107 \"024543742098\"^81 \"024543781875\"^67 \"023272342654\"^39 \"014633169522\"^32 \"024543560067\"^30 \"883929154012\"^24 \"023272342630\"^20 \"708431390614\"^18 \"024543263739\"^18 \"886973561621\"^17 \"023272341381\"^16 \"030206742121\"^14 \"885370332889\"^12 \"883929106172\"^8 \"886111287055\"^8\n",
      "\n",
      "{'query': '\"star wars\"', 'limit': 5, 'params': {'qf': ['name', 'manufacturer', 'long_description'], 'boost': 'sum(1,query($boost_query))', 'boost_query': '\"024543742180\"^1489 \"400032015667\"^186 \"024543742074\"^127 \"024543559856\"^117 \"014633169546\"^107 \"024543742098\"^81 \"024543781875\"^67 \"023272342654\"^39 \"014633169522\"^32 \"024543560067\"^30 \"883929154012\"^24 \"023272342630\"^20 \"708431390614\"^18 \"024543263739\"^18 \"886973561621\"^17 \"023272341381\"^16 \"030206742121\"^14 \"885370332889\"^12 \"883929106172\"^8 \"886111287055\"^8'}, 'fields': ['upc', 'name', 'manufacturer', 'short_description', 'score'], 'sort': 'score desc, upc asc'}\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div id=\"demo\">\n",
       "\t<center><input style=\"width:40%\" readonly type=\"text\" name=\"q\" value=\"\"star wars\"\">\n",
       "\t<input readonly type=\"submit\" value=\"Search\">\n",
       "\t</center>\n",
       "    <div class=\"results\">\n",
       "    \t\n",
       "\n",
       "    </div>\n",
       "</div>\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/400032015667.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Star Wars - The Complete Saga - Blu-ray Disc\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> LucasFilm</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/883929154012.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Star Wars: The Clone Wars - The Complete Season Three [4 Discs] - DVD\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> LucasFilm</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/886973561621.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Star Wars: The Clone War - Original Soundtrack - CD\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> Sony Classics</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/883929106172.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Star Wars: The Clone Wars - The Complete Season Two [4 Discs] - DVD\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong>  </p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/708431390614.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> LeapFrog - Leapster Explorer Learning Game: Star Wars The Clone Wars\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> LeapFrog</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "query = '\"star wars\"'\n",
    "\n",
    "boosted_request = boosted_product_search_request(query, anti_spam_collection)\n",
    "response = products_collection.search(**boosted_request)\n",
    "\n",
    "print(products_collection.transform_request(**boosted_request))\n",
    "display_product_search(query, response[\"docs\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Mixing multiple signal types"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Listing 8.6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Aggregating Signals to Create Signals Boosts...\n",
      "Wiping \"signals_boosts_weighted_types\" collection\n",
      "Creating \"signals_boosts_weighted_types\" collection\n",
      "Status: Success\n",
      "Successfully written 152252 documents\n",
      "Signals Aggregation Completed!\n"
     ]
    }
   ],
   "source": [
    "#One Signal per User - Anti-Spam\n",
    "#Sometimes needs rerunning\n",
    "mixed_signal_types_aggregation_query = \"\"\"\n",
    "SELECT query, doc, ((1 * click_boost) + (10 * add_to_cart_boost) +\n",
    "                    (25 * purchase_boost)) AS boost FROM (\n",
    "  SELECT query, doc, \n",
    "    SUM(click) AS click_boost,\n",
    "    SUM(add_to_cart) AS add_to_cart_boost,\n",
    "    SUM(purchase) AS purchase_boost FROM (  \n",
    "      SELECT lower(q.target) AS query, cap.target AS doc, \n",
    "        IF(cap.type = 'click', 1, 0) AS click, \n",
    "        IF(cap.type = 'add-to-cart', 1, 0) AS  add_to_cart, \n",
    "        IF(cap.type = 'purchase', 1, 0) AS purchase\n",
    "      FROM signals cap LEFT JOIN signals q on cap.query_id = q.query_id\n",
    "      WHERE (cap.type != 'query' AND q.type = 'query')\n",
    "    ) AS raw_signals\n",
    "  GROUP BY query, doc) AS per_type_boosts\"\"\"\n",
    "\n",
    "type_weighted_collection = \\\n",
    "  aggregate_signals(signals_collection, \"signals_boosts_weighted_types\",\n",
    "                    mixed_signal_types_aggregation_query)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Time Decay"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Listing 8.7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Aggregating Signals to Create Signals Boosts...\n",
      "Wiping \"signals_boosts_time_weighted\" collection\n",
      "Creating \"signals_boosts_time_weighted\" collection\n",
      "Status: Success\n",
      "Successfully written 152251 documents\n",
      "Signals Aggregation Completed!\n"
     ]
    }
   ],
   "source": [
    "half_life_days = 30\n",
    "target_date = \"2020-06-01\" #date of latest signal in our dataset. In live system use now().\n",
    "signal_weight = 1 #can make this a function to differentiate weights for different signal types\n",
    "\n",
    "time_decay_aggregation = f\"\"\"\n",
    "SELECT query, doc, SUM(time_weighted_boost) AS boost FROM (\n",
    "  SELECT user, query, doc,\n",
    "  {signal_weight} * POW(0.5, (DATEDIFF('{target_date}', raw_signals.t) / {half_life_days}))\n",
    "  AS time_weighted_boost FROM (\n",
    "    SELECT c.user AS user, lower(q.target) AS query, c.target AS doc,\n",
    "    MAX(c.signal_time) as t\n",
    "    FROM signals c LEFT JOIN signals q ON c.query_id = q.query_id\n",
    "    WHERE c.type = 'click' AND q.type = 'query'\n",
    "          AND c.signal_time <= '{target_date}'\n",
    "    GROUP BY c.user, q.target, c.target\n",
    "  ) AS raw_signals \n",
    ") AS time_weighted_signals\n",
    "GROUP BY query, doc\n",
    "ORDER BY boost DESC\"\"\"\n",
    "time_weighted_collection = \\\n",
    "    aggregate_signals(signals_collection, \"signals_boosts_time_weighted\", \n",
    "                      time_decay_aggregation)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Boost Documents:\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[{'query': 'star wars', 'doc': '024543742180', 'boost': 50.275649588684246},\n",
       " {'query': 'star wars', 'doc': '023272342654', 'boost': 14.386081175228192},\n",
       " {'query': 'star wars', 'doc': '024543742074', 'boost': 10.978708113139781},\n",
       " {'query': 'star wars', 'doc': '883929154012', 'boost': 10.22196625832087},\n",
       " {'query': 'star wars', 'doc': '023272342630', 'boost': 8.08610476717647},\n",
       " {'query': 'star wars', 'doc': '886973561621', 'boost': 7.196654524422255},\n",
       " {'query': 'star wars', 'doc': '024543742098', 'boost': 6.411867877358415},\n",
       " {'query': 'star wars', 'doc': '030206742121', 'boost': 6.0339109822265105},\n",
       " {'query': 'star wars', 'doc': '014633169546', 'boost': 5.7322561332539275},\n",
       " {'query': 'star wars', 'doc': '708431390614', 'boost': 5.200090923395828},\n",
       " {'query': 'star wars', 'doc': '024543559856', 'boost': 4.795950895622491},\n",
       " {'query': 'star wars', 'doc': '023272341381', 'boost': 2.9199459597275252},\n",
       " {'query': 'star wars', 'doc': '014633169522', 'boost': 2.2727988663619274},\n",
       " {'query': 'star wars', 'doc': '886971404722', 'boost': 2.244924096618746},\n",
       " {'query': 'star wars', 'doc': '024543560067', 'boost': 1.6538835179903377},\n",
       " {'query': 'star wars', 'doc': '400032015667', 'boost': 1.448048337976181},\n",
       " {'query': 'star wars', 'doc': '883929153992', 'boost': 0.9339199409434634},\n",
       " {'query': 'star wars', 'doc': '023272341633', 'boost': 0.8908987181403393},\n",
       " {'query': 'star wars', 'doc': '024543781875', 'boost': 0.7423932331629598},\n",
       " {'query': 'star wars', 'doc': '024543212768', 'boost': 0.7405487761432821}]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Boost Query: \n",
      "\"024543742180\"^50.275649588684246 \"023272342654\"^14.386081175228192 \"024543742074\"^10.978708113139781 \"883929154012\"^10.22196625832087 \"023272342630\"^8.08610476717647 \"886973561621\"^7.196654524422255 \"024543742098\"^6.411867877358415 \"030206742121\"^6.0339109822265105 \"014633169546\"^5.7322561332539275 \"708431390614\"^5.200090923395828 \"024543559856\"^4.795950895622491 \"023272341381\"^2.9199459597275252 \"014633169522\"^2.2727988663619274 \"886971404722\"^2.244924096618746 \"024543560067\"^1.6538835179903377 \"400032015667\"^1.448048337976181 \"883929153992\"^0.9339199409434634 \"023272341633\"^0.8908987181403393 \"024543781875\"^0.7423932331629598 \"024543212768\"^0.7405487761432821\n",
      "\n",
      "{'query': '\"star wars\"', 'limit': 5, 'params': {'qf': ['name', 'manufacturer', 'long_description'], 'boost': 'sum(1,query($boost_query))', 'boost_query': '\"024543742180\"^50.275649588684246 \"023272342654\"^14.386081175228192 \"024543742074\"^10.978708113139781 \"883929154012\"^10.22196625832087 \"023272342630\"^8.08610476717647 \"886973561621\"^7.196654524422255 \"024543742098\"^6.411867877358415 \"030206742121\"^6.0339109822265105 \"014633169546\"^5.7322561332539275 \"708431390614\"^5.200090923395828 \"024543559856\"^4.795950895622491 \"023272341381\"^2.9199459597275252 \"014633169522\"^2.2727988663619274 \"886971404722\"^2.244924096618746 \"024543560067\"^1.6538835179903377 \"400032015667\"^1.448048337976181 \"883929153992\"^0.9339199409434634 \"023272341633\"^0.8908987181403393 \"024543781875\"^0.7423932331629598 \"024543212768\"^0.7405487761432821'}, 'fields': ['upc', 'name', 'manufacturer', 'short_description', 'score'], 'sort': 'score desc, upc asc'}\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div id=\"demo\">\n",
       "\t<center><input style=\"width:40%\" readonly type=\"text\" name=\"q\" value=\"\"star wars\"\">\n",
       "\t<input readonly type=\"submit\" value=\"Search\">\n",
       "\t</center>\n",
       "    <div class=\"results\">\n",
       "    \t\n",
       "\n",
       "    </div>\n",
       "</div>\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/883929154012.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Star Wars: The Clone Wars - The Complete Season Three [4 Discs] - DVD\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> LucasFilm</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/886973561621.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Star Wars: The Clone War - Original Soundtrack - CD\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> Sony Classics</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/886971404722.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Star Wars: The Corellian Edition (Snys) - CD\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> UNKNOWN</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/886971404722.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Star Wars: The Corellian Edition [DSD CD] - CD\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> Sony Music Distribution (USA)</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/708431390614.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> LeapFrog - Leapster Explorer Learning Game: Star Wars The Clone Wars\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> LeapFrog</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "query = '\"star wars\"'\n",
    "\n",
    "boosted_request = boosted_product_search_request(query, time_weighted_collection)\n",
    "print(products_collection.transform_request(**boosted_request))\n",
    "\n",
    "response = products_collection.search(**boosted_request)\n",
    "display_product_search(query, response[\"docs\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wiping \"products_with_signals_boosts\" collection\n",
      "Creating \"products_with_signals_boosts\" collection\n",
      "Adding \"boosts\" field type to collection\n",
      "Status: Success\n",
      "Loading Products\n",
      "Schema: \n",
      "root\n",
      " |-- upc: string (nullable = true)\n",
      " |-- name: string (nullable = true)\n",
      " |-- manufacturer: string (nullable = true)\n",
      " |-- short_description: string (nullable = true)\n",
      " |-- long_description: string (nullable = true)\n",
      "\n",
      "Successfully written 48194 documents\n"
     ]
    }
   ],
   "source": [
    "from aips.data_loaders.products import load_dataframe\n",
    "boosted_products_collection = engine.create_collection(\"products_with_signals_boosts\")\n",
    "boosted_products_collection.write(load_dataframe(\"data/retrotech/products.csv\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Listing 8.8"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Successfully written 18721 documents\n"
     ]
    }
   ],
   "source": [
    "from aips.data_loaders import index_time_boosts\n",
    "\n",
    "boosts_collection = engine.get_collection(\"normalized_signals_boosts\")\n",
    "boosted_products_collection = \\\n",
    "    engine.get_collection(\"products_with_signals_boosts\")\n",
    "\n",
    "boosted_products = index_time_boosts.load_dataframe(\n",
    "    products_collection,\n",
    "    boosts_collection)\n",
    "\n",
    "boosted_products_collection.write(boosted_products)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "## Index-time Signals Boosting Query"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Listing 8.9"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_boosted_search_request(query, boost_field):\n",
    "    request = product_search_request(query)\n",
    "    request[\"index_time_boost\"] = (boost_field, query)\n",
    "    return request"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div id=\"demo\">\n",
       "\t<center><input style=\"width:40%\" readonly type=\"text\" name=\"q\" value=\"ipad\">\n",
       "\t<input readonly type=\"submit\" value=\"Search\">\n",
       "\t</center>\n",
       "    <div class=\"results\">\n",
       "    \t\n",
       "\n",
       "    </div>\n",
       "</div>\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/885909457588.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Apple&#xAE; - iPad&#xAE; 2 with Wi-Fi - 16GB - Black\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> Apple&#xAE;</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/885909457595.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Apple&#xAE; - iPad&#xAE; 2 with Wi-Fi - 32GB - Black\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> Apple&#xAE;</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/885909471812.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Apple&#xAE; - iPad&#xAE; 2 with Wi-Fi - 16GB - White\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> Apple&#xAE;</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/885909472376.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> Apple&#xAE; - iPad&#xAE; 2 with Wi-Fi - 32GB - White\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> Apple&#xAE;</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t\n",
       "    \t<div style=\"position: relative; width: 100%; height:auto; overflow: auto;\">\n",
       "\t    \t<div style=\"position: relative; float:left; width: 120px; margin-top:5px\">\n",
       "\t    \t\t<img style=\"width:250px; height: auto; max-height:150px\" src=\"../../data/retrotech/images/843404073153.jpg\">\n",
       "\t    \t</div>\n",
       "\t    \t<div style=\"position:relative; float:left; clear:none; width: 80%; height:auto\">\n",
       "\t    \t\t<p style=\"font-size:24px; padding-left: 50px;\"><strong>\t\tName:</strong> ZAGG - InvisibleSHIELD for Apple&#xAE; iPad&#xAE; 2 - Clear\n",
       "\t\t\t\t\t<br><strong>\t\tManufacturer:</strong> ZAGG</p>\n",
       "\t    \t\t</p>\n",
       "\t    \t</div>\n",
       "    \t</div>\n",
       "    \t\n",
       "\t\t<div style=\"position:relative; clear:both; content: ' '; display: block; height: 1px; margin-top: 10px; margin-bottom:20px\">\n",
       "\t\t\t<hr style=\"color: gray; width: 95%;\" />\n",
       "\t\t</div>\n",
       "\t\t"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "query = \"ipad\"\n",
    "boosted_query = get_boosted_search_request(query, \"signals_boosts\")\n",
    "response = boosted_products_collection.search(**boosted_query)\n",
    "display_product_search(query, response[\"docs\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Up next: Chapter 9 - [Personalized Search](../ch09/1.personalization.ipynb)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
